// 代理模式能将代理对象与被调用对象分离，降低了系统的耦合度。代理模式在客户端和目标对象之间起到一个中介作用，这样可以起到保护目标对象的作用
// 代理对象可以扩展目标对象的功能；通过修改代理对象就可以了，符合开闭原则；

// 处理请求速度可能有差别，非直接访问存在开销
// 不同点
// 装饰者模式实现上和代理模式类似

// 装饰者模式： 扩展功能，原有功能不变且可直接使用
// 代理模式： 显示原有功能，但是经过限制之后的

// 应用场景:
// 代购, 明星经纪人,  科学上网
// 模式特点:
// 代理对象可预先处理请求，再决定是否转交给本体；
// 代理和本体对外显示接口保持一致性
// 代理对象仅对本体做一次包装



// 虚拟代理（将开销大的运算延迟到需要时执行）
// 缓存代理（为开销大的运算结果提供缓存）
// 保护代理（黑白双簧，代理充当黑脸，拦截非分要求）
// 防火墙代理（控制网络资源的访问）
// 远程代理（为一个对象在不同的地址控件提供局部代表）
// 智能引用代理（访问对象执行一些附加操作）
// 写时复制代理（延迟对象复制过程，对象需要真正修改时才进行）

//模式实现: 1, 创建代理对象,  代理对象可以对请求进行处理, 再决定是否转交给本体
// 代理和本体对外接口保持一致

// 例如: 黑名单代理

// let backPhoneList = ['189xxxx1234'];

// let ProxyAcceptPhone = function(phone){
//     console.log("电话正在接入");
//     if(backPhoneList.includes(phone)){
//         console.log("屏蔽黑名单电话");
//     }else{
//         // 转换
//         AcceptPhone.call(this, phone);
//     }
// }

// let AcceptPhone = function(phone){
//     console.log("接听电话---", phone);
// }
// ProxyAcceptPhone('189xxxx1234');
// ProxyAcceptPhone('189xxxx1236');


// 虚拟代理在图片预加载的应用
// 本体
var myImage = (function(){
    var imgNode = document.createElement('img');
    document.body.appendChild(imgNode);
    return {
        setSrc: function(src) {
            imgNode.src = src;
        }
    }
})();


// 代理
var proxyImage = (function(){
    var img = new Image;
    img.onload = function() {
        myImage.setSrc(img.src);             // 图片加载完设置真实图片src
    }
    return {
        setSrc: function(src) {
            myImage.setSrc('./loading.gif');  // 预先设置图片src为loading图
            img.src = src;
        }
    }
})();

// 外部调用
proxyImage.setSrc('./product.png');           // 有loading图的图片预加载效果